{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Torch Adam - RMS Spot Size Optimization\n",
    "\n",
    "- Note that optimization in PyTorch is fundamentally the same as the standard optimization using NumPy/SciPy. The only user-facing difference is the use of a torch-based optimizer."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import optiland.backend as be\n",
    "from optiland import optic, optimization\n",
    "\n",
    "be.set_backend(\"torch\")  # Set the backend to PyTorch\n",
    "be.grad_mode.enable()  # Enable gradient tracking"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Define a starting lens:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 1000x400 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "lens = optic.Optic()\n",
    "\n",
    "# add surfaces\n",
    "lens.add_surface(index=0, thickness=be.inf)\n",
    "lens.add_surface(index=1, thickness=7, radius=1000, material=\"N-SF11\", is_stop=True)\n",
    "lens.add_surface(index=2, thickness=30, radius=-1000)\n",
    "lens.add_surface(index=3)\n",
    "\n",
    "# set aperture\n",
    "lens.set_aperture(aperture_type=\"EPD\", value=15)\n",
    "\n",
    "# add field\n",
    "lens.set_field_type(field_type=\"angle\")\n",
    "lens.add_field(y=0)\n",
    "\n",
    "# add wavelength\n",
    "lens.add_wavelength(value=0.55, is_primary=True)\n",
    "\n",
    "# draw lens\n",
    "_ = lens.draw(num_rays=5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Define optimization problem:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "problem = optimization.OptimizationProblem()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Add operands (targets for optimization):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "\"\"\"\n",
    "Define RMS spot size properties for the optimization:\n",
    "    1. Surface number = -1, implying last surface (image surface)\n",
    "    2. Normalized field coordinates (Hx, Hy) = (0, 0)\n",
    "    3. Number of rays = 5, corresponds to number of rings in hexapolar distribution\n",
    "        (see distribution documentation)\n",
    "    4. Wavelength = 0.55 µm\n",
    "    5. Pupil distribution = hexapolar\n",
    "\"\"\"\n",
    "\n",
    "input_data = {\n",
    "    \"optic\": lens,\n",
    "    \"surface_number\": -1,\n",
    "    \"Hx\": 0,\n",
    "    \"Hy\": 0,\n",
    "    \"num_rays\": 5,\n",
    "    \"wavelength\": 0.55,\n",
    "    \"distribution\": \"hexapolar\",\n",
    "}\n",
    "\n",
    "# add RMS spot size operand\n",
    "problem.add_operand(\n",
    "    operand_type=\"rms_spot_size\",\n",
    "    target=0,\n",
    "    weight=1,\n",
    "    input_data=input_data,\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Define variables - let radius of curvature vary for both surfaces, at surface index 1 and 2:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "problem.add_variable(lens, \"radius\", surface_number=1)\n",
    "problem.add_variable(lens, \"radius\", surface_number=2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Check initial merit function value and system properties:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "╒════╤════════════════════════╤═══════════════════╕\n",
      "│    │   Merit Function Value │   Improvement (%) │\n",
      "╞════╪════════════════════════╪═══════════════════╡\n",
      "│  0 │                30.0924 │                 0 │\n",
      "╘════╧════════════════════════╧═══════════════════╛\n",
      "╒════╤════════════════╤══════════╤══════════════╤══════════════╤══════════╤═════════╤═════════╤════════════════╕\n",
      "│    │ Operand Type   │   Target │ Min. Bound   │ Max. Bound   │   Weight │   Value │   Delta │   Contrib. [%] │\n",
      "╞════╪════════════════╪══════════╪══════════════╪══════════════╪══════════╪═════════╪═════════╪════════════════╡\n",
      "│  0 │ rms spot size  │        0 │              │              │        1 │   5.486 │   5.486 │            100 │\n",
      "╘════╧════════════════╧══════════╧══════════════╧══════════════╧══════════╧═════════╧═════════╧════════════════╛\n",
      "╒════╤═════════════════╤═══════════╤═════════╤══════════════╤══════════════╕\n",
      "│    │ Variable Type   │   Surface │   Value │ Min. Bound   │ Max. Bound   │\n",
      "╞════╪═════════════════╪═══════════╪═════════╪══════════════╪══════════════╡\n",
      "│  0 │ radius          │         1 │    1000 │              │              │\n",
      "│  1 │ radius          │         2 │   -1000 │              │              │\n",
      "╘════╧═════════════════╧═══════════╧═════════╧══════════════╧══════════════╛\n"
     ]
    }
   ],
   "source": [
    "problem.info()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Define optimizer:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "optimizer = optimization.TorchAdamOptimizer(problem)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Run optimization:\n",
    "\n",
    "- Define learning rate (`lr`) and the learning rate decay factor (`gamma`)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  Step 0001/250, Loss: 30.092424\n",
      "  Step 0011/250, Loss: 29.753153\n",
      "  Step 0021/250, Loss: 29.367258\n",
      "  Step 0031/250, Loss: 28.914419\n",
      "  Step 0041/250, Loss: 28.367346\n",
      "  Step 0051/250, Loss: 27.686949\n",
      "  Step 0061/250, Loss: 26.812805\n",
      "  Step 0071/250, Loss: 25.643610\n",
      "  Step 0081/250, Loss: 23.993845\n",
      "  Step 0091/250, Loss: 21.483864\n",
      "  Step 0101/250, Loss: 17.212940\n",
      "  Step 0111/250, Loss: 8.675235\n",
      "  Step 0121/250, Loss: 2.685997\n",
      "  Step 0131/250, Loss: 0.765375\n",
      "  Step 0141/250, Loss: 0.009119\n",
      "  Step 0151/250, Loss: 0.021494\n",
      "  Step 0161/250, Loss: 0.039819\n",
      "  Step 0171/250, Loss: 0.014043\n",
      "  Step 0181/250, Loss: 0.007309\n",
      "  Step 0191/250, Loss: 0.008413\n",
      "  Step 0201/250, Loss: 0.007488\n",
      "  Step 0211/250, Loss: 0.007278\n",
      "  Step 0221/250, Loss: 0.007291\n",
      "  Step 0231/250, Loss: 0.007234\n",
      "  Step 0241/250, Loss: 0.007232\n",
      "  Step 0250/250, Loss: 0.007219\n"
     ]
    }
   ],
   "source": [
    "res = optimizer.optimize(n_steps=250, lr=0.1, gamma=0.99, disp=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Print merit function value and system properties after optimization:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "╒════╤════════════════════════╤═══════════════════╕\n",
      "│    │   Merit Function Value │   Improvement (%) │\n",
      "╞════╪════════════════════════╪═══════════════════╡\n",
      "│  0 │             0.00721827 │                 0 │\n",
      "╘════╧════════════════════════╧═══════════════════╛\n",
      "╒════╤════════════════╤══════════╤══════════════╤══════════════╤══════════╤═════════╤═════════╤════════════════╕\n",
      "│    │ Operand Type   │   Target │ Min. Bound   │ Max. Bound   │   Weight │   Value │   Delta │   Contrib. [%] │\n",
      "╞════╪════════════════╪══════════╪══════════════╪══════════════╪══════════╪═════════╪═════════╪════════════════╡\n",
      "│  0 │ rms spot size  │        0 │              │              │        1 │   0.085 │   0.085 │            100 │\n",
      "╘════╧════════════════╧══════════╧══════════════╧══════════════╧══════════╧═════════╧═════════╧════════════════╛\n",
      "╒════╤═════════════════╤═══════════╤══════════╤══════════════╤══════════════╕\n",
      "│    │ Variable Type   │   Surface │    Value │ Min. Bound   │ Max. Bound   │\n",
      "╞════╪═════════════════╪═══════════╪══════════╪══════════════╪══════════════╡\n",
      "│  0 │ radius          │         1 │  49.3377 │              │              │\n",
      "│  1 │ radius          │         2 │ -53.7622 │              │              │\n",
      "╘════╧═════════════════╧═══════════╧══════════╧══════════════╧══════════════╛\n"
     ]
    }
   ],
   "source": [
    "problem.info()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Draw final lens:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 1000x400 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "_ = lens.draw(num_rays=5)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "optiland (3.13.2)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
